package cn.shujuhai.qtadmin.platform.pluging.security;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jetbrains.annotations.NotNull;
import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.*;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.ObjectMapper;

import cn.hutool.core.text.CharSequenceUtil;
import cn.shujuhai.qtadmin.platform.pluging.result.Result;

/**
 * 登陆成功返回处理器
 *
 * @author dch798
 * @date 2021/08/26 22:02
 **/
@Component
public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    public MyAuthenticationFailureHandler() {
        super("/login?error");
    }

    /**
     *
     * @param request
     *            request
     * @return acceptMediaType
     */
    public static MediaType getRequestPrimaryAcceptMediaType(@NotNull HttpServletRequest request) {
        String accept = request.getHeader("Accept");
        MediaType acceptMediaType;
        if (CharSequenceUtil.isEmpty(accept)) {
            acceptMediaType = MediaType.APPLICATION_JSON;
        } else {
            String[] str = accept.split(",");
            if (str.length > 0) {
                try {
                    acceptMediaType = MediaType.valueOf(str[0]);
                } catch (InvalidMediaTypeException ex) {
                    acceptMediaType = MediaType.APPLICATION_JSON;
                }
            } else {
                acceptMediaType = MediaType.APPLICATION_JSON;
            }
        }
        return acceptMediaType;
    }

    /**
     *
     * @param httpServletRequest
     *            httpServletRequest
     * @param httpServletResponse
     *            httpServletResponse
     * @param e
     *            e
     * @throws IOException
     *             IOException
     * @throws ServletException
     *             ServletException
     */
    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
        @NotNull AuthenticationException e) throws IOException, ServletException {
        e.printStackTrace();
        if (e instanceof LockedException) {
            e = new LockedException("账户被锁定，请联系管理员!", e);
        } else if (e instanceof CredentialsExpiredException) {
            e = new CredentialsExpiredException("密码过期，请联系管理员!", e);
        } else if (e instanceof AccountExpiredException) {
            e = new AccountExpiredException("账户过期，请联系管理员!", e);
        } else if (e instanceof DisabledException) {
            e = new DisabledException("账户被禁用，请联系管理员!", e);
        } else if (e instanceof BadCredentialsException) {
            e = new BadCredentialsException("用户名或者密码输入错误，请重新输入!", e);
        }
        MediaType acceptMediaType = getRequestPrimaryAcceptMediaType(httpServletRequest);
        if (MediaType.TEXT_HTML.compareTo(acceptMediaType) == 0) {
            super.onAuthenticationFailure(httpServletRequest, httpServletResponse, e);
        } else if (MediaType.APPLICATION_JSON.compareTo(acceptMediaType) == 0
            || MediaType.ALL.compareTo(acceptMediaType) == 0) {
            httpServletResponse.setContentType("application/json; charset=UTF-8");
            PrintWriter writer = httpServletResponse.getWriter();
            writer.write(new ObjectMapper().writeValueAsString(Result.failure(e.getMessage())));
            writer.flush();
            writer.close();
        }
    }

}
